import 'package:flutter/cupertino.dart';
import 'package:kq_flutter_core_widget/widgets/keepalive/kq_keep_alive.dart';

import '../update/update_view.dart';

class StackView extends StatefulWidget {
  ///初始显示的界面
  final Widget? Function(StackViewState state) init;

  const StackView({
    super.key,
    required this.init,
  });

  @override
  State<StatefulWidget> createState() => StackViewState();
}

class StackViewState extends State<StackView> {
  final List<Widget> _stack = [];
  UpdateViewState? _updateViewState;

  final PageController _controller = PageController();

  bool _isBack = false;

  ///参数
  dynamic arguments;

  ///返回回调出缓存
  final Map<Widget, Function(dynamic result)> _callbacks = {};

  int _index = 0;

  @override
  void initState() {
    super.initState();
    Widget? initWidget = widget.init.call(this);
    if (initWidget != null) {
      _stack.add(initWidget);
    }
  }

  @override
  Widget build(BuildContext context) {
    return UpdateView(build: (UpdateViewState state) {
      _updateViewState = state;
      return PageView.builder(
        itemCount: _stack.length,
        controller: _controller,
        physics: const NeverScrollableScrollPhysics(),
        scrollDirection: Axis.vertical,
        itemBuilder: (BuildContext context, int index) {
          return KqKeepAlive(child: _stack[index]);
        },
        onPageChanged: (index) {
          if (_isBack) {
            _stack.removeLast();
            _isBack = false;
            _updateViewState?.update();
          }
          _index = index;
        },
      );
    });
  }

  ///以Map的方式获取参数，如果传入的参数不是Map形式，则需使用[arguments]获取参数
  S? getArg<S>(String key) {
    if (arguments == null) {
      return null;
    }
    if (arguments is! Map) {
      return null;
    }
    return arguments[key];
  }

  ///添加一个widget，即打开一个界面。
  ///[page] 需要打开的界面。
  ///[arguments] 打开时需要给下一个界面传递的参数。
  ///[callback]打开的界面关闭时，回传的参数。
  addWidget(
    Widget page, {
    dynamic arguments,
    Function(dynamic result)? callback,
    bool showAnimate = true,
  }) {
    _stack.add(page);
    if (showAnimate) {
      _controller.animateToPage(
        _stack.length - 1,
        duration: const Duration(milliseconds: 200),
        curve: Curves.ease,
      );
    } else {
      _controller.jumpToPage(_stack.length - 1);
    }

    ///传参赋值，取值时，直接使用[arguments]取值，或者使用[getArg]方法取值
    this.arguments = arguments;

    ///存储回调，当初始界面为空时，使用临时key存储
    if (callback != null) {
      _callbacks.putIfAbsent(page, () => callback);
    }
    if (_updateViewState != null) {
      _updateViewState?.update();
    } else {
      setState(() {});
    }
  }

  ///回退，返回上一个界面。
  ///[bool] 返回true表示成功返回上一级，
  ///返回false表示返回失败，已是最后一个界面，不可继续返回。
  bool back({
    dynamic result,
    bool showAnimate = true,
  }) {
    if (_stack.length > 1) {
      _isBack = true;
      if (showAnimate) {
        _controller.animateToPage(
          _stack.length - 2,
          duration: const Duration(milliseconds: 200),
          curve: Curves.ease,
        );
      } else {
        _controller.jumpToPage(_stack.length - 2);
      }

      ///移除当前界面的callback，如果存在，调用call，并传递result的值
      _callbacks.remove(_stack[_index])?.call(result);
    } else {
      close(result: result);
    }

    if (_stack.isNotEmpty) {
      return true;
    } else {
      return false;
    }
  }

  bool backAble() {
    return _stack.isNotEmpty;
  }

  /// 关闭
  close({dynamic result}) {
    _callbacks[_stack[_index]]?.call(result);
    _stack.clear();
    _callbacks.clear();
    setState(() {});
  }

  @override
  void dispose() {
    super.dispose();
    _stack.clear();
    _callbacks.clear();
  }
}
